"""
CausalEngine 模块 - 因果分析引擎基类

提供因果分析的基础功能和通用方法，包括：
1. 指标聚类信息的加载和管理
2. 因果分析的通用流程实现
3. container内部和container-service间因果关系分析
4. 结果解析和处理
"""

import json
import os
import logging
from abc import ABC, abstractmethod
from typing import Dict, List, Tuple, Mapping
import pandas as pd
import numpy as np
from tqdm import tqdm
import sys
from datetime import datetime

from source.data_processor.utils.experiment_data import ExperimentData
from source.detect.metric.metric_detection_result import MetricDetectionResult
from source.localize.graph.casualEdge import CausalityEdge
from source.localize.graph.systemDependencyGraph import SystemDependencyGraphBuilder

# 配置日志
logger = logging.getLogger(__name__)
# 设置日志级别为INFO，确保info级别的日志可以显示
logger.setLevel(logging.INFO)


class baseCasualEngine(ABC):
    """
    因果分析引擎基类

    实现了因果分析的基础框架，包括：
    1. 数据预处理和验证
    2. 聚类信息管理
    3. 跨集群和单集群因果分析
    4. 结果解析和格式化

    子类需要实现：
    - _run_algorithm: 具体的因果发现算法
    - _get_method_name: 算法名称
    """

    # 定义列名分隔符，用于分隔cmdb_id和metric_name
    COLUMN_SEPARATOR = "$"

    def __init__(self, config):
        """
        因果分析引擎基类

        实现了因果分析的基础框架，包括：
        1. 数据预处理和验证
        2. 聚类信息管理
        3. 跨集群和单集群因果分析
        4. 结果解析和格式化

        子类需要实现：
        - _run_algorithm: 具体的因果发现算法
        - _get_method_name: 算法名称
        """
        self.config = config
        self.MIN_DATA_POINTS = getattr(config, "MIN_CASUAL_SIZE", 10)
        self.SAVE_DIR = getattr(config, "SAVE_DIR", "./data")
        self.MAX_LAG = getattr(config, "MAX_LAG", 6)
        self.cluster_info: Dict[str, Dict] = {}

    @abstractmethod
    def _run_algorithm(
        self,
        data: pd.DataFrame,
    ) -> np.ndarray | Dict:
        """
        执行具体的因果发现算法

        Args:
            data: 输入数据，DataFrame格式的时间序列数据

        Returns:
            np.ndarray | Dict:
                - 对于普通算法返回邻接矩阵
                - 对于Granger等算法返回包含val_matrix、p_matrix和alpha的字典
        """
        raise NotImplementedError

    def _run_analysis(
        self,
        data: pd.DataFrame,
        valid_metrics_list: List[List[Tuple[str, str]]],
        cmdb_id: str,
        target_cmdb_id: str = None,
        bidirectional: bool = False,
        from_entity: str = "container",
        to_entity: str = "service",
    ) -> List[CausalityEdge]:
        if len(data) < self.MIN_DATA_POINTS:
            return []

        data = data.replace([np.inf, -np.inf], np.nan).dropna()

        if data.empty:
            return []

        adj_matrix = self._run_algorithm(data)

        return self._parse_results(
            adj_matrix=adj_matrix,
            cluster_cols=list(data.columns),
            valid_metrics_list=valid_metrics_list,
            cmdb_id=cmdb_id,
            target_cmdb_id=target_cmdb_id,
            bidirectional=bidirectional,
            from_entity=from_entity,
            to_entity=to_entity,
        )

    def analyze_causality(
        self,
        neo_graph: SystemDependencyGraphBuilder,
        experiment_data: ExperimentData,
        metric_result: MetricDetectionResult = None,
    ) -> List[CausalityEdge]:
        """
        执行因果分析
        分析顺序：
        1. 首先分析Container内部的指标因果关系
        2. 然后分析Service内部的指标因果关系
        3. 最后分析Container和Service之间的指标因果关系

        参数:
            neo_graph: 图数据库对象，用于获取实体间的依赖关系
            experiment_data: 实验数据对象，包含原始指标数据
            metric_result: 指标异常检测结果，如果提供则只分析有异常的指标

        返回:
            List[CausalityEdge]: 所有因果边的列表
        """
        logger.info("开始因果分析...")

        if metric_result is None:
            logger.warning("未提供指标异常检测结果，将分析所有指标")

        # 步骤1: 从指标数据和异常检测结果中提取需要分析的指标
        pivot_df_map, anomalous_metrics = self._prepare_data_for_analysis(
            experiment_data, metric_result
        )

        if not pivot_df_map:
            logger.error("无法获取有效的指标数据，因果分析终止")
            return []

        all_causal_edges = []
        entity_analysis_config = [
            # 实体内部分析
            {"entity_type": "container", "message": "Container内部指标因果关系"},
            {"entity_type": "service", "message": "Service内部指标因果关系"},
            # 跨实体分析
            {
                "from_entity": "container",
                "to_entity": "service",
                "message": "Container->Service因果关系",
                "bidirectional": True,
            },
            {
                "from_entity": "service",
                "to_entity": "service",
                "message": "Service->Service因果关系",
                "bidirectional": True,
            },
        ]

        # 执行实体内部分析
        for config in entity_analysis_config[:2]:
            entity_type = config["entity_type"]
            logger.info(f"开始分析{config['message']}...")

            internal_edges = self._analyze_entity_internal_causality(
                pivot_df_map, entity_type, anomalous_metrics.get(entity_type, {})
            )
            logger.info(f"发现{len(internal_edges)}个{config['message']}")
            all_causal_edges.extend(internal_edges)

        # 执行跨实体分析
        for config in entity_analysis_config[2:]:
            from_entity = config["from_entity"]
            to_entity = config["to_entity"]
            logger.info(f"开始分析{config['message']}...")

            cross_edges = self._analyze_cross_entity_causality(
                pivot_df_map,
                neo_graph,
                from_entity,
                to_entity,
                config["bidirectional"],
                anomalous_metrics.get(from_entity, {}),
                anomalous_metrics.get(to_entity, {}),
            )
            logger.info(f"发现{len(cross_edges)}个{config['message']}")
            all_causal_edges.extend(cross_edges)

        logger.info(f"因果分析完成，共发现{len(all_causal_edges)}个因果关系")

        return all_causal_edges

    def _prepare_data_for_analysis(
        self,
        experiment_data: ExperimentData,
        metric_result: MetricDetectionResult = None,
    ) -> Tuple[Dict[str, pd.DataFrame], Dict[str, Dict[str, List[str]]]]:
        """
        准备因果分析所需的数据

        参数:
            experiment_data: 实验数据对象
            metric_result: 指标异常检测结果

        返回:
            Tuple[Dict[str, pd.DataFrame], Dict[str, Dict[str, List[str]]]]:
                - 按实体类型组织的透视表数据
                - 按实体类型和ID组织的异常指标列表
        """
        # 获取原始指标数据
        metrics_df = experiment_data.metrics_df
        if metrics_df.empty:
            logger.error("指标数据为空")
            return {}, {}

        # 标准化实体类型 - 确保只有container、service和node类型
        entity_type_mapping = {"pod": "container", "interface": "service"}

        # 复制原始数据并标准化实体类型
        metrics_df_mapped = metrics_df.copy()
        metrics_df_mapped["entity_type"] = metrics_df_mapped["entity_type"].replace(
            entity_type_mapping
        )

        # 只保留标准化后的实体类型
        standard_entity_types = ["container", "service", "node"]
        metrics_df_mapped = metrics_df_mapped[
            metrics_df_mapped["entity_type"].isin(standard_entity_types)
        ]

        if metrics_df_mapped.empty:
            logger.error("标准化后的指标数据为空")
            return {}, {}

        # 提取异常指标
        anomalous_metrics = {"container": {}, "service": {}, "node": {}}

        if metric_result and metric_result.anomaly_intervals_by_cmdb:
            # 使用anomaly_intervals_by_cmdb提取异常指标
            for (
                cmdb_id,
                intervals_list,
            ) in metric_result.anomaly_intervals_by_cmdb.items():
                # 获取该cmdb_id的entity_type
                entity_rows = metrics_df_mapped[metrics_df_mapped["cmdb_id"] == cmdb_id]
                if entity_rows.empty:
                    continue

                # 获取最常见的entity_type，使用标准化后的类型
                entity_type = entity_rows["entity_type"].value_counts().idxmax()

                if entity_type not in anomalous_metrics:
                    continue

                # 从intervals中提取异常指标
                anomalous_metric_names = []
                for interval_obj in intervals_list:
                    # 首先尝试直接从 interval_obj 获取 metric_name
                    try:
                        metric_name = interval_obj["metric_name"]
                        if metric_name not in anomalous_metric_names:
                            anomalous_metric_names.append(metric_name)
                    except (KeyError, TypeError):
                        # 如果直接获取失败，则遍历字典寻找 metric_name
                        for metric_key, metric_data in interval_obj.items():
                            # 获取指标名称，可以使用key或者value中的metric_name字段
                            metric_name = metric_data.get("metric_name", metric_key)
                            if metric_name not in anomalous_metric_names:
                                anomalous_metric_names.append(metric_name)

                if anomalous_metric_names:
                    anomalous_metrics[entity_type][cmdb_id] = anomalous_metric_names

        # 构建透视表 - 按标准化后的实体类型分组
        pivot_df_map = {}

        # 预先筛选需要的列，避免不必要的列参与透视
        metrics_df_subset = metrics_df_mapped[
            ["timestamp", "entity_type", "cmdb_id", "metric_name", "value"]
        ].copy()

        # 为每种标准实体类型创建透视表
        for entity_type in standard_entity_types:
            entity_metrics = metrics_df_subset[
                metrics_df_subset["entity_type"] == entity_type
            ]
            if entity_metrics.empty:
                continue

            try:
                # 按ID、指标名称和时间戳透视
                pivot_df = pd.pivot_table(
                    entity_metrics,
                    index="timestamp",
                    columns=["cmdb_id", "metric_name"],
                    values="value",
                    aggfunc="mean",
                )

                # 将多级索引列名转换为单级索引，使用类变量定义的分隔符
                pivot_df.columns = [
                    f"{col[0]}{self.COLUMN_SEPARATOR}{col[1]}"
                    for col in pivot_df.columns
                ]

                # 确保时间索引是有序的
                pivot_df.sort_index(inplace=True)

                pivot_df_map[entity_type] = pivot_df
            except Exception as e:
                logger.error(f"构建{entity_type}透视表时出错: {str(e)}")

        return pivot_df_map, anomalous_metrics

    def _filter_metrics_by_anomaly(
        self,
        df_columns: pd.Index,
        entity_id: str,
        anomalous_metrics: Dict[str, List[str]] = None,
    ) -> List[str]:
        """
        根据异常指标筛选列名

        参数:
            df_columns: 数据框的列索引
            entity_id: 实体ID
            anomalous_metrics: 异常指标字典 {entity_id: [metric_names]}

        返回:
            List[str]: 筛选后的列名列表
        """
        # 使用pandas的向量化操作筛选列
        prefix = f"{entity_id}{self.COLUMN_SEPARATOR}"
        # 使用startswith过滤列 - 这是向量化操作
        entity_cols = df_columns[df_columns.str.startswith(prefix)].tolist()

        # 如果提供了异常指标，只返回异常列
        if anomalous_metrics and entity_id in anomalous_metrics:
            metrics_to_analyze = set(anomalous_metrics[entity_id])
            # 使用pandas的str方法提取指标名
            col_metrics = pd.Series(entity_cols).str.split(
                self.COLUMN_SEPARATOR, n=1, expand=True
            )[1]
            # 创建布尔掩码
            mask = col_metrics.isin(metrics_to_analyze)
            # 应用掩码过滤列
            entity_cols = pd.Series(entity_cols)[mask].tolist()

        return entity_cols

    def _build_metrics_mapping(self, columns: List[str]) -> List[List[Tuple[str, str]]]:
        """
        构建列名到指标映射

        参数:
            columns: 列名列表，格式为"entity_id{COLUMN_SEPARATOR}metric_name"

        返回:
            List[List[Tuple[str, str]]]: 指标映射列表
        """
        if not columns:
            return []

        # 使用pandas的向量化操作
        column_series = pd.Series(columns)
        # 拆分列名，使用类变量定义的分隔符
        split_result = column_series.str.split(self.COLUMN_SEPARATOR, n=1, expand=True)

        # 构建映射列表
        metrics_list = []
        for i in range(len(split_result)):
            if len(split_result.iloc[i]) == 2:
                entity_id, metric_name = split_result.iloc[i]
                metrics_list.append([(entity_id, metric_name)])
            else:
                # 处理异常情况
                metrics_list.append([])

        return metrics_list

    def _analyze_entity_internal_causality(
        self,
        pivot_df_map: Dict[str, pd.DataFrame],
        entity_type: str,
        anomalous_metrics: Dict[str, List[str]] = None,
    ) -> List[CausalityEdge]:
        """
        分析单个实体类型内部的指标因果关系

        参数:
            pivot_df_map: 按实体类型组织的透视表数据
            entity_type: 实体类型 ('container', 'service', 'node')
            anomalous_metrics: 该实体类型的异常指标 {cmdb_id: [metric_names]}

        返回:
            List[CausalityEdge]: 因果边列表
        """
        results = []

        if entity_type not in pivot_df_map:
            logger.info(f"{entity_type}类型的数据不存在")
            return results

        entity_df = pivot_df_map[entity_type]
        if entity_df.empty:
            logger.info(f"{entity_type}类型的数据为空")
            return results

        # 从透视表列名中提取所有唯一的cmdb_id
        entity_ids = set()
        for col_name in entity_df.columns:
            parts = col_name.split(self.COLUMN_SEPARATOR, 1)
            if len(parts) == 2:
                cmdb_id, _ = parts
                entity_ids.add(cmdb_id)

        logger.info(f"发现 {entity_type} 类型的 {len(entity_ids)} 个实体")

        # 如果提供了异常指标，只分析有异常的实体
        if anomalous_metrics:
            entity_ids = entity_ids.intersection(set(anomalous_metrics.keys()))
            logger.info(f"其中 {len(entity_ids)} 个实体有异常指标需要分析")

        # 转换为列表并使用tqdm显示进度
        entity_ids_list = list(entity_ids)

        # 对每个实体内部的指标进行因果分析，使用tqdm显示进度
        for entity_id in tqdm(
            entity_ids_list, desc=f"分析{entity_type}内部因果关系", unit="实体"
        ):
            # 筛选实体的异常指标列
            entity_cols = self._filter_metrics_by_anomaly(
                entity_df.columns, entity_id, anomalous_metrics
            )

            if len(entity_cols) < 2:  # 至少需要两个指标才能分析因果关系
                logger.info(f"{entity_type} {entity_id} 的有效指标数量不足，跳过分析")
                continue

            # 使用DataFrame的loc索引，避免不必要的copy操作
            entity_data = entity_df[entity_cols]

            # 构建指标映射
            valid_metrics_list = self._build_metrics_mapping(entity_cols)

            # 过滤方差为0的列
            entity_data, valid_metrics_list = self._filter_zero_variance(
                entity_data, valid_metrics_list
            )

            if (
                entity_data.empty
                or len(entity_data.columns) < 2
                or len(entity_data) < self.MIN_DATA_POINTS
            ):
                logger.info(
                    f"{entity_type} {entity_id} 的数据量或有效指标数量不足，跳过分析"
                )
                continue

            try:
                # 执行因果分析
                edges = self._run_analysis(
                    data=entity_data,
                    valid_metrics_list=valid_metrics_list,
                    cmdb_id=entity_id,
                    from_entity=entity_id,
                    to_entity=entity_id,
                )
                logger.info(
                    f"在 {entity_type} {entity_id} 内发现 {len(edges)} 个因果关系"
                )
                results.extend(edges)
            except Exception as e:
                logger.error(
                    f"{entity_type.capitalize()} {entity_id} 内部因果分析失败: {str(e)}"
                )

        return results

    def _analyze_cross_entity_causality(
        self,
        pivot_df_map: Dict[str, pd.DataFrame],
        neo_graph: SystemDependencyGraphBuilder,
        from_entity: str,
        to_entity: str,
        bidirectional: bool = True,
        from_anomalous_metrics: Dict[str, List[str]] = None,
        to_anomalous_metrics: Dict[str, List[str]] = None,
    ) -> List[CausalityEdge]:
        """
        分析跨实体之间的指标因果关系

        参数:
            pivot_df_map: 按实体类型组织的透视表数据
            neo_graph: 图数据库对象，用于获取实体依赖关系
            from_entity: 源实体类型 ('container', 'service', 'node')
            to_entity: 目标实体类型 ('container', 'service', 'node')
            bidirectional: 是否进行双向分析
            from_anomalous_metrics: 源实体的异常指标
            to_anomalous_metrics: 目标实体的异常指标

        返回:
            List[CausalityEdge]: 因果边列表
        """
        if not all(key in pivot_df_map for key in [from_entity, to_entity]):
            logger.info(f"缺少 {from_entity} 或 {to_entity} 类型的数据")
            return []

        results = []

        # 获取实体之间的依赖关系
        entity_relations = {}

        try:
            if from_entity == "container" and to_entity == "service":
                # 获取容器-服务依赖关系
                entity_relations = neo_graph.get_pod_interfaces()
                logger.info(
                    f"获取到 {len(entity_relations)} 个container-service依赖关系"
                )
            elif from_entity == "service" and to_entity == "service":
                # 获取服务间调用关系
                entity_relations = neo_graph.get_interface_dependencies(reverse=True)
                logger.info(f"获取到 {len(entity_relations)} 个service-service调用关系")
            else:
                logger.error(f"不支持的实体类型组合: {from_entity} -> {to_entity}")
                return []
        except Exception as e:
            logger.error(f"获取依赖关系时出错: {str(e)}")
            return []

        # 获取源实体和目标实体的数据框
        from_df = pivot_df_map[from_entity]
        to_df = pivot_df_map[to_entity]

        # 从透视表列名中提取所有唯一的源实体cmdb_id
        from_entity_ids = set()
        for col_name in from_df.columns:
            parts = col_name.split(self.COLUMN_SEPARATOR, 1)
            if len(parts) == 2:
                cmdb_id, _ = parts
                from_entity_ids.add(cmdb_id)

        # 确定需要分析的源实体，必须存在于依赖关系中
        from_entities = from_entity_ids.intersection(set(entity_relations.keys()))
        logger.info(f"发现 {len(from_entities)} 个有依赖关系的 {from_entity} 实体")

        # 如果提供了异常指标，只分析有异常的源实体
        if from_anomalous_metrics:
            from_entities = from_entities.intersection(
                set(from_anomalous_metrics.keys())
            )
            logger.info(
                f"其中 {len(from_entities)} 个 {from_entity} 实体有异常指标需要分析"
            )

        # 批量处理共同时间戳，避免重复计算
        common_timestamps = from_df.index.intersection(to_df.index)
        if len(common_timestamps) < self.MIN_DATA_POINTS:
            logger.info(
                f"共同时间戳数量不足 ({len(common_timestamps)}), 至少需要 {self.MIN_DATA_POINTS}"
            )
            return results

        # 转换为列表并使用tqdm显示进度
        from_entities_list = list(from_entities)
        progress_desc = f"分析{from_entity}->{to_entity}因果关系"

        # 使用tqdm显示进度
        for from_id in tqdm(from_entities_list, desc=progress_desc, unit="实体"):
            # 获取此源实体关联的目标实体
            related_to_entities = set(entity_relations.get(from_id, []))

            # 从透视表列名中提取所有目标实体cmdb_id
            to_entity_ids = set()
            for col_name in to_df.columns:
                parts = col_name.split(self.COLUMN_SEPARATOR, 1)
                if len(parts) == 2:
                    cmdb_id, _ = parts
                    to_entity_ids.add(cmdb_id)

            # 找出实际存在于数据中的目标实体
            related_to_entities = related_to_entities.intersection(to_entity_ids)

            # 如果提供了目标实体的异常指标，只分析有异常的目标实体
            if to_anomalous_metrics:
                related_to_entities = related_to_entities.intersection(
                    set(to_anomalous_metrics.keys())
                )

            # 记录关联实体数量
            if related_to_entities:
                logger.info(
                    f"{from_entity} {from_id} 关联到 {len(related_to_entities)} 个 {to_entity} 实体"
                )

            # 筛选源实体的异常指标列
            from_cols = self._filter_metrics_by_anomaly(
                from_df.columns, from_id, from_anomalous_metrics
            )

            if not from_cols or not related_to_entities:
                continue

            # 预先获取源实体在共同时间戳的数据，避免重复计算
            from_data = from_df.loc[common_timestamps, from_cols]

            # 使用内部tqdm显示每个源实体的目标实体分析进度
            for to_id in tqdm(
                related_to_entities,
                desc=f"{from_id}的目标实体分析",
                unit="实体",
                leave=False,
            ):
                # 筛选目标实体的异常指标列
                to_cols = self._filter_metrics_by_anomaly(
                    to_df.columns, to_id, to_anomalous_metrics
                )

                if not to_cols:
                    continue

                # 获取目标实体在共同时间戳的数据
                to_data = to_df.loc[common_timestamps, to_cols]

                # 高效合并数据 - 使用pandas concat，axis=1表示按列合并
                merged_df = pd.concat([from_data, to_data], axis=1)

                # 构建指标映射
                from_metrics_list = self._build_metrics_mapping(from_cols)
                to_metrics_list = self._build_metrics_mapping(to_cols)
                joint_metrics_list = from_metrics_list + to_metrics_list

                # 过滤方差为0的列
                merged_df, joint_metrics_list = self._filter_zero_variance(
                    merged_df, joint_metrics_list
                )

                if merged_df.empty or len(merged_df) < self.MIN_DATA_POINTS:
                    continue

                try:
                    # 执行因果分析
                    edges = self._run_analysis(
                        data=merged_df,
                        valid_metrics_list=joint_metrics_list,
                        cmdb_id=from_id,
                        target_cmdb_id=to_id,
                        bidirectional=bidirectional,
                        from_entity=from_id,
                        to_entity=to_id,
                    )
                    if edges:
                        logger.info(
                            f"在 {from_entity} {from_id} -> {to_entity} {to_id} 间发现 {len(edges)} 个因果关系"
                        )
                    results.extend(edges)
                except Exception as e:
                    logger.error(
                        f"{from_entity} {from_id} 与 {to_entity} {to_id} 的因果分析失败: {str(e)}"
                    )

        logger.info(
            f"{from_entity}->{to_entity}分析完成，共发现 {len(results)} 个因果关系"
        )
        return results

    def _parse_results(
        self,
        adj_matrix: np.ndarray | Dict,
        cluster_cols: List[str],
        valid_metrics_list: List[List[Tuple[str, str]]],
        cmdb_id: str,
        target_cmdb_id: str = None,
        bidirectional: bool = False,
        from_entity: str = "container",
        to_entity: str = "service",
    ) -> List[CausalityEdge]:
        """
        解析因果分析结果

        支持两种分析模式：
        1. 跨集群分析：分析不同实体间的因果关系（可选双向分析）
        2. 单集群内部分析：分析同一实体内不同指标间的因果关系
        """
        method = self._get_method_name()
        results = []

        if target_cmdb_id:  # 跨集群分析
            # 定义需要分析的实体对
            entity_pairs = [(cmdb_id, target_cmdb_id, from_entity, to_entity)]
            if bidirectional:
                entity_pairs.append((target_cmdb_id, cmdb_id, to_entity, from_entity))

            # 对每对实体进行因果分析
            for source_id, target_id, src_type, dst_type in entity_pairs:
                # 根据列名前缀确定源和目标的列，使用类变量定义的分隔符
                source_prefix = f"{source_id}{self.COLUMN_SEPARATOR}"
                target_prefix = f"{target_id}{self.COLUMN_SEPARATOR}"

                source_cols = [
                    col for col in cluster_cols if col.startswith(source_prefix)
                ]
                target_cols = [
                    col for col in cluster_cols if col.startswith(target_prefix)
                ]

                # 获取对应的指标列表
                source_indices = [
                    i
                    for i, col in enumerate(cluster_cols)
                    if col.startswith(source_prefix)
                ]
                target_indices = [
                    i
                    for i, col in enumerate(cluster_cols)
                    if col.startswith(target_prefix)
                ]

                source_metrics = [valid_metrics_list[i] for i in source_indices]
                target_metrics = [valid_metrics_list[i] for i in target_indices]

                # 获取对应的子矩阵
                if isinstance(adj_matrix, dict):
                    val_matrix = adj_matrix["val_matrix"]
                    p_matrix = adj_matrix["p_matrix"]
                    alpha = adj_matrix["alpha"]

                    cross_matrix = {
                        "val_matrix": val_matrix[
                            np.ix_(source_indices, target_indices)
                        ],
                        "p_matrix": p_matrix[np.ix_(source_indices, target_indices)],
                        "alpha": alpha,
                    }
                else:
                    cross_matrix = adj_matrix[np.ix_(source_indices, target_indices)]

                # 解析当前方向的因果关系
                edges = self.parse_cross_cluster_causality(
                    source_cols,
                    target_cols,
                    source_metrics,
                    target_metrics,
                    cross_matrix,
                    source_id,
                    target_id,
                    method,
                    src_type,
                    dst_type,
                )
                results.extend(edges)

        else:  # 单集群内部分析
            edges = self.parse_cross_cluster_causality(
                cluster_cols,
                cluster_cols,
                valid_metrics_list,
                valid_metrics_list,
                adj_matrix,
                cmdb_id,
                cmdb_id,
                method,
                from_entity,
                from_entity,  # 同一实体内部分析，源和目标类型相同
            )
            results.extend(edges)

        return results

    def _filter_zero_variance(
        self, df: pd.DataFrame, valid_metrics_list: List[List[Tuple[str, str]]]
    ) -> Tuple[pd.DataFrame, List[List[Tuple[str, str]]]]:
        """
        过滤掉方差为0的列及其对应的指标

        Args:
            df: 输入数据框
            valid_metrics_list: 有效指标列表

        Returns:
            Tuple[pd.DataFrame, List[List[Tuple[str, str]]]]: 过滤后的数据框和指标列表
        """
        # 计算每列的方差 - 使用pandas的原生操作
        variances = df.var()

        # 获取方差不为0的列索引 - 向量化操作
        valid_cols = variances[variances > 0].index

        if len(valid_cols) < len(df.columns):
            logger.warning(f"移除了 {len(df.columns) - len(valid_cols)} 个方差为0的列")

            # 获取要保留的列的索引 - 使用pandas的索引操作
            valid_indices = [i for i, col in enumerate(df.columns) if col in valid_cols]

            # 过滤数据框和指标列表 - 直接使用列索引筛选
            filtered_df = df[valid_cols]
            filtered_metrics = [valid_metrics_list[i] for i in valid_indices]

            return filtered_df, filtered_metrics

        return df, valid_metrics_list

    @abstractmethod
    def _get_method_name(self) -> str:
        """获取算法方法名称"""
        raise NotImplementedError

    @staticmethod
    def parse_cross_cluster_causality(
        source_cols: List[str],
        target_cols: List[str],
        source_metrics: List[List[Tuple[str, str]]],
        target_metrics: List[List[Tuple[str, str]]],
        adj_matrix: Dict,
        source_id: str,
        target_id: str,
        method: str,
        from_entity_type: str = "container",
        to_entity_type: str = "service",
    ) -> List[CausalityEdge]:
        edges = []
        source_size = len(source_cols)
        target_size = len(target_cols)

        val_matrix = adj_matrix["val_matrix"]
        p_matrix = adj_matrix["p_matrix"]
        alpha = adj_matrix["alpha"]
        max_lag = val_matrix.shape[2]

        # 处理跨集群因果关系
        for i in range(source_size):
            for j in range(target_size):
                for lag in range(max_lag):
                    strength = val_matrix[i, j, lag]
                    p_value = p_matrix[i, j, lag]  # 获取p值
                    significant = p_value < alpha
                    if not significant:
                        continue

                    # 检查并获取代表指标
                    if not (
                        i < len(source_metrics)
                        and source_metrics[i]
                        and j < len(target_metrics)
                        and target_metrics[j]
                    ):
                        continue
                    cause_metric = source_metrics[i][0][1]
                    effect_metric = target_metrics[j][0][1]

                    # 跳过同一实体的同一指标之间的因果关系
                    if source_id == target_id and cause_metric == effect_metric:
                        continue

                    # 根据不同算法处理滞后值
                    if method.startswith("Granger"):
                        # Granger中lag=0实际上是滞后1
                        actual_lag = lag + 1
                    else:
                        # PCMCI/PCMCIPlus中lag就是实际滞后
                        actual_lag = lag

                    edge = CausalityEdge(
                        cause_pod=source_id,
                        cause_metric=cause_metric,
                        effect_pod=target_id,
                        effect_metric=effect_metric,
                        strength=abs(strength),
                        p_value=p_value,
                        time_lag=actual_lag,
                        method=f"{method}",
                        from_entity_type=from_entity_type,
                        to_entity_type=to_entity_type,
                    )
                    edges.append(edge)

        return edges
